package edu.nepu.bigdata.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.*;

import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author mr
 */
public class JedisPikaUtil {
	
	private static final Logger LOG = LoggerFactory.getLogger(JedisPikaUtil.class);
	
	private static JedisPoolConfig getConfig() {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(3);
		config.setMaxIdle(3);
		config.setMaxWaitMillis(6000);
		config.setTestOnBorrow(true);
		config.setTestOnReturn(true);
		config.setTestWhileIdle(true);
		config.setNumTestsPerEvictionRun(-1);
		config.setMinEvictableIdleTimeMillis(60_000);
		config.setTimeBetweenEvictionRunsMillis(30_000);
		return config;
	}
	
	/**
	 * pika单机模式
	 *
	 * @param hostPort
	 * @param password
	 * @return
	 */
	public static ShardedJedis getJedisPika(String hostPort, String password) {
		String[] split = hostPort.split(":");
		JedisShardInfo jedisShardInfo1 = new JedisShardInfo(split[0], Integer.parseInt(split[1]));
		jedisShardInfo1.setPassword(password);
		List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
		list.add(jedisShardInfo1);
		return new ShardedJedisPool(getConfig(), list).getResource();
	}
	
	/**
	 * pika哨兵模式
	 *
	 * @param hostPort
	 * @param pikaMaster
	 * @param password
	 * @return
	 */
	public static Jedis getJedisPika(String hostPort, String pikaMaster, String password) {
		Set<String> sentinelSet = getSentinelSet(hostPort);

		JedisSentinelPool sentinelPool = new JedisSentinelPool(pikaMaster, sentinelSet, getConfig(), password);
		
		return sentinelPool.getResource();
	}
	
	public static JedisSentinelPool getPikaSentinelPool(String hostPort, String pikaMaster, String password) {
		Set<String> sentinelSet = getSentinelSet(hostPort);
		return new JedisSentinelPool(pikaMaster, sentinelSet, getConfig(), password);
	}

	public static JedisSentinelPool getPikaSentinelPool(
			String hostPort,
			String pikaMaster,
			String password,
			int timeout) {
		Set<String> sentinelSet = getSentinelSet(hostPort);
		return new JedisSentinelPool(pikaMaster, sentinelSet, getConfig(), timeout, password);
	}

	private static Set<String> getSentinelSet(String hostPort) {
		String[] split = hostPort.split(",");
		Set<String> sentinelSet = new HashSet<String>();
		for (String s : split) {
			sentinelSet.add(s);
		}
		return sentinelSet;
	}

	public static String[] doSscan(final Jedis conn, final String key) {
		String cursor = "0";
		ScanParams scanParams = new ScanParams();
		scanParams.count(1000);
		
		HashSet<String> set = new HashSet<>();
		do {
			ScanResult<String> sscan = conn.sscan(key, cursor, scanParams);
			cursor = sscan.getStringCursor();
			List<String> result = sscan.getResult();
			result.forEach(x -> {
				set.add(x);
			});
			
			try {
				TimeUnit.MILLISECONDS.sleep(2);
			} catch (InterruptedException e) {
				LOG.error("sleep {} ", e);
			}
		} while (!cursor.equalsIgnoreCase("0"));
		return set.toArray(new String[set.size()]);
	}
	
	public static HashMap<String, String> doHscan(final Jedis jedis, final String key) throws ParseException {
		
		String cursor = "0";
		ScanParams scanParams = new ScanParams();
		scanParams.count(1000);
		
		HashMap<String, String> map = new HashMap<>();
		
		do {
			ScanResult<Map.Entry<String, String>> hscan = jedis.hscan(key, cursor, scanParams);
			cursor = hscan.getStringCursor();
			
			List<Map.Entry<String, String>> result = hscan.getResult();
			for (Map.Entry<String, String> entry : result) {
				map.put(entry.getKey(), entry.getValue());
			}
			
		} while (!cursor.equalsIgnoreCase("0"));
		
		return map;
	}



	/**
	 * 获取uid对应的北斗ID
	 */
	public static String getUUserId (Jedis jedis, String projectId, String uid) {
		return jedis.get(String.format("u:%s:%s", projectId, uid));
	}

	/**
	 * 获取cid对应的北斗ID
	 */
	public static String getCUserId (Jedis jedis, String projectId, String cid) {
		return jedis.get(String.format("c:%s:%s", projectId, cid));
	}

	/**
	 * 获取手机号对应的北斗ID
	 */
	public static String getMUserId (Jedis jedis, String projectId, String mobile) {
		return jedis.get(String.format("m:%s:%s", projectId, mobile));
	}
}
